package concurrency;

import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

class ReaderWriterListTest {
    private final static int SIZE = 100;

    private ReaderWriterList<Integer> mList = new ReaderWriterList<Integer>(SIZE, 0);

    private ExecutorService mExec = Executors.newCachedThreadPool();

    private static Random sRand = new Random(47);

    public ReaderWriterListTest(int readers, int writers) {
        for (int i = 0; i < readers; i++) {
            mExec.execute(new Reader());
        }
        for (int i = 0; i < writers; i++) {
            mExec.execute(new Writer());
        }
    }

    private class Reader implements Runnable {
        @Override
        public void run() {
            try {
                while (!Thread.interrupted()) {
                    for (int i = 0; i < SIZE; i++) {
                        mList.get(i);
                        TimeUnit.MILLISECONDS.sleep(1);
                    }
                }
            } catch (InterruptedException e) {
                // Acceptable way to exit
                // e.printStackTrace();
            }
        }

    }

    private class Writer implements Runnable {
        @Override
        public void run() {
            try {
                // 2 second test
                for(int i = 0; i < 20; i++) {
                    mList.set(i, sRand.nextInt());
                    TimeUnit.MILLISECONDS.sleep(100);
                }
            } catch(InterruptedException e) {
                // Acceptable way to exit
            }
            System.out.println("Writer finished, shutting down");
            mExec.shutdownNow();
        }
    }
}
